home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / AmiVoGL_MDEV.lha / src / polygons.c < prev    next >
C/C++ Source or Header  |  1994-04-12  |  24KB  |  1,278 lines

  1. #include <stdio.h>
  2. #include "vogl.h"
  3.  
  4. /* --------------------------------------------------------------------- */
  5.  
  6. #ifdef AZTEC_C
  7. #include <math.h>
  8. #else
  9. extern    double    cos();
  10. extern    double    sin();
  11. #endif
  12.  
  13. /* ---------------------------------------------------------------------
  14.  * Definitions:
  15.  */
  16.  
  17. #define MAX(x, y)    ((x) > (y) ? (x) : (y))
  18. #define MIN(x, y)    ((x) < (y) ? (x) : (y))
  19. #define ABS(x)        ((x) < 0 ? -(x) : (x))
  20.  
  21. /* ---------------------------------------------------------------------
  22.  * Local Variables:
  23.  */
  24. static float    F[6][4], S[6][4], I[4], p[MAXVERTS][4];
  25. static int    nout, first[6], numv;
  26. static long    polymodeflag = PYM_FILL;
  27. static int    ip1[MAXVERTS], ip2[MAXVERTS];
  28.  
  29. /*
  30.  *  Orientation of backfacing polygons(in screen coords)
  31.  */
  32. static    int    clockwise = 1;
  33.  
  34. /* ---------------------------------------------------------------------
  35.  * Prototypes:
  36.  */
  37. #ifdef __PROTOTYPE__
  38.  
  39. static void dopoly(int);                               /* polygons.c      */
  40. static void polyoutline( int, int[], int[]);           /* polygons.c      */
  41. static int checkbacki(void);                           /* polygons.c      */
  42. static void polyclip(register int);                    /* polygons.c      */
  43. static void shclip( float[4], int);                    /* polygons.c      */
  44. static void shclose(int);                              /* polygons.c      */
  45. static intersect( int, register Vector,                /* polygons.c      */
  46.    register Vector);
  47. static visible(int);                                   /* polygons.c      */
  48.  
  49. #else    /* __PROTOTYPE__ */
  50.  
  51. static void dopoly();                                  /* polygons.c      */
  52. static void polyoutline();                             /* polygons.c      */
  53. static int checkbacki();                               /* polygons.c      */
  54. static void polyclip();                                /* polygons.c      */
  55. static void shclip();                                  /* polygons.c      */
  56. static void shclose();                                 /* polygons.c      */
  57. static intersect();                                    /* polygons.c      */
  58. static visible();                                      /* polygons.c      */
  59.  
  60. #endif    /* __PROTOTYPE__ */
  61.  
  62. /*
  63.  * concave
  64.  *
  65.  *    signal wether or not polygons are concave (not a lot of use at the moment).
  66.  */
  67. void concave(Boolean yesno)
  68. {
  69. vdevice.concave = yesno;
  70. }
  71.  
  72. /* ------------------------------------------------------------------------ */
  73.  
  74. /*
  75.  * backface
  76.  *
  77.  *    Turns on culling of backfacing polygons. A polygon is
  78.  * backfacing if it's orientation in *screen* coords is clockwise.
  79.  */
  80. void backface(int onoff)
  81. {
  82. vdevice.attr->a.backface = onoff;
  83. clockwise = 1;
  84. }
  85.  
  86. /* ------------------------------------------------------------------------ */
  87.  
  88. /*
  89.  * frontface
  90.  *
  91.  *    Turns on culling of frontfacing polygons. A polygon is
  92.  * frontfacing if it's orientation in *screen* coords is anti-clockwise.
  93.  */
  94. void frontface(int onoff)
  95. {
  96. vdevice.attr->a.backface = onoff;
  97. clockwise = 0;
  98. }
  99.  
  100. /* ------------------------------------------------------------------------ */
  101.  
  102. /*
  103.  * polymode
  104.  *
  105.  *    Sets the polygon filling mode - only filled or outlined supported
  106.  */
  107. void polymode(long mode)
  108. {
  109. /*
  110.  * On older SGI Machines this call used to work... On the newer
  111.  * boxes it doesn't do anything. If you want the old stuff then
  112.  * #define OLD_SGI_BOXES somewhere.
  113.  */
  114. #ifdef OLD_SGI_BOXES
  115. polymodeflag = mode;
  116. #endif
  117. }
  118.  
  119. /* ------------------------------------------------------------------------ */
  120.  
  121. /*
  122.  * dopoly
  123.  *
  124.  *    do a transformed polygon with n edges using fill
  125.  */
  126. static void dopoly(int n)
  127. {
  128. int    i;
  129. char    buf[100];
  130.  
  131. if (n > MAXVERTS) {
  132.     sprintf(buf, "dopoly: can't fill a polygon with more than %d vertices", MAXVERTS);
  133.     verror(buf);
  134.     }
  135.  
  136. if (!vdevice.clipoff) {
  137.     polyclip(n);
  138.     }
  139. else {
  140.     nout = n;
  141.     for (i = 0; i < n; i++) {
  142.         ip1[i] = WtoVx(p[i]);
  143.         ip2[i] = WtoVy(p[i]);
  144.         }
  145.     }
  146.  
  147.  
  148. if (vdevice.attr->a.backface && checkbacki()) {
  149.     vdevice.fill = 0;
  150.     return;
  151.     }
  152.  
  153. if (vdevice.fill) {
  154.     if (nout > 2) {
  155.         (*vdevice.dev.Vfill)(nout, ip1, ip2);
  156.         }
  157.     }
  158. else {
  159.     vdevice.cpVx = ip1[0];
  160.     vdevice.cpVy = ip2[0];
  161.     vdevice.cpVvalid = 0;
  162.     polyoutline(nout, ip1, ip2);
  163.     }
  164.  
  165. vdevice.fill = 0;
  166. }
  167.  
  168. /* ------------------------------------------------------------------------ */
  169.  
  170. /*
  171.  * polyoutline
  172.  *
  173.  *    draws a polygon outline from already transformed points.
  174.  */
  175. static void polyoutline(
  176.   int n,
  177.   int ipx[],
  178.   int ipy[])
  179. {
  180. int    i;
  181.  
  182. if (n > 2) {
  183.     for (i = 1; i < n; i++) {
  184.         (*vdevice.dev.Vdraw)(ipx[i], ipy[i]);
  185.  
  186.         vdevice.cpVx = ipx[i];
  187.         vdevice.cpVy = ipy[i];
  188.         }
  189.     (*vdevice.dev.Vdraw)(ipx[0], ipy[0]);
  190.  
  191.     vdevice.cpVx = ipx[0];
  192.     vdevice.cpVy = ipy[0];
  193.     }
  194. }
  195.  
  196. /* ------------------------------------------------------------------------ */
  197.  
  198. /*
  199.  * polyobj
  200.  *
  201.  *    construct a polygon from a object token list.
  202.  */
  203. void polyobj(
  204.   int n,
  205.   Token dp[],
  206.   int fill)
  207. {
  208. int    i, j;
  209. float    vect[4], result[4];
  210.  
  211. for (i = 0, j = 0; i < n; i++, j += 3) {
  212.     vect[V_X] = dp[j + V_X].f;
  213.     vect[V_Y] = dp[j + V_Y].f;
  214.     vect[V_Z] = dp[j + V_Z].f;
  215.     vect[V_W] = 1;
  216.     multvector(result, vect, vdevice.transmat->m);
  217.     p[i][V_X] = result[V_X];
  218.     p[i][V_Y] = result[V_Y];
  219.     p[i][V_Z] = result[V_Z];
  220.     p[i][V_W] = result[V_W];
  221.     }
  222.  
  223. if (fill)
  224. vdevice.fill = polymodeflag;
  225. else
  226. vdevice.fill = 0;
  227.  
  228. dopoly(n);
  229.  
  230. vdevice.cpW[V_X] = dp[V_X].f;
  231. vdevice.cpW[V_Y] = dp[V_Y].f;
  232. vdevice.cpW[V_Z] = dp[V_Z].f;
  233. }
  234.  
  235. /* ------------------------------------------------------------------------ */
  236.  
  237. /*
  238.  * poly2
  239.  *
  240.  *    construct a polygon from an (x, y) array of points provided by the user.
  241.  */
  242. void poly2(
  243.   long nv,
  244.   float dp[][2])
  245. {
  246. int    i;
  247. float    np[MAXVERTS][3];
  248.  
  249. if (!vdevice.initialised)
  250. verror("poly2: vogl not initialised");
  251.  
  252. vdevice.fill = 0;
  253.  
  254. for (i = 0; i < (int)nv; i++) {
  255.     np[i][V_X] = dp[i][V_X];
  256.     np[i][V_Y] = dp[i][V_Y];
  257.     np[i][V_Z] = 0.0;
  258.     }
  259.  
  260. poly(nv, np);
  261. }
  262.  
  263. /* ------------------------------------------------------------------------ */
  264.  
  265. /*
  266.  * poly2i
  267.  *
  268.  *    construct a polygon from an (x, y) array of points provided by the user.
  269.  * Icoord version.
  270.  */
  271. void poly2i(
  272.   long nv,
  273.   Icoord dp[][2])
  274. {
  275. int    i;
  276. float    np[MAXVERTS][3];
  277.  
  278. if (!vdevice.initialised)
  279. verror("poly2i: vogl not initialised");
  280.  
  281. vdevice.fill = 0;
  282.  
  283. for (i = 0; i < (int)nv; i++) {
  284.     np[i][V_X] = dp[i][V_X];
  285.     np[i][V_Y] = dp[i][V_Y];
  286.     np[i][V_Z] = 0.0;
  287.     }
  288.  
  289. poly(nv, np);
  290. }
  291.  
  292. /* ------------------------------------------------------------------------ */
  293.  
  294. /*
  295.  * poly2s
  296.  *
  297.  *    construct a polygon from an (x, y) array of points provided by the user.
  298.  * Scoord version.
  299.  */
  300. void poly2s(
  301.   long nv,
  302.   Scoord dp[][2])
  303. {
  304. int    i;
  305. float    np[MAXVERTS][3];
  306.  
  307. if (!vdevice.initialised)
  308. verror("poly2s: vogl not initialised");
  309.  
  310. vdevice.fill = 0;
  311.  
  312. for (i = 0; i < (int)nv; i++) {
  313.     np[i][V_X] = dp[i][V_X];
  314.     np[i][V_Y] = dp[i][V_Y];
  315.     np[i][V_Z] = 0.0;
  316.     }
  317.  
  318. poly(nv, np);
  319. }
  320.  
  321. /* ------------------------------------------------------------------------ */
  322.  
  323. /*
  324.  * polyi
  325.  *
  326.  *    construct a polygon from an (x, y, z) array of points provided by the user.
  327.  * Icoord version.
  328.  */
  329. void polyi(
  330.   long nv,
  331.   Icoord dp[][3])
  332. {
  333. int    i;
  334. float    np[MAXVERTS][3];
  335.  
  336. if (!vdevice.initialised)
  337. verror("polyi: vogl not initialised");
  338.  
  339. vdevice.fill = 0;
  340.  
  341. for (i = 0; i < (int)nv; i++) {
  342.     np[i][V_X] = dp[i][V_X];
  343.     np[i][V_Y] = dp[i][V_Y];
  344.     np[i][V_Z] = dp[i][V_Z];
  345.     }
  346.  
  347. poly(nv, np);
  348. }
  349.  
  350. /* ------------------------------------------------------------------------ */
  351.  
  352. /*
  353.  * polys
  354.  *
  355.  *    construct a polygon from an (x, y, z) array of points provided by the user.
  356.  * Scoord version.
  357.  */
  358. void polys(
  359.   long nv,
  360.   Scoord dp[][3])
  361. {
  362. int    i;
  363. float    np[MAXVERTS][3];
  364.  
  365. if (!vdevice.initialised)
  366. verror("poly2s: vogl not initialised");
  367.  
  368. vdevice.fill = 0;
  369.  
  370. for (i = 0; i < (int)nv; i++) {
  371.     np[i][V_X] = dp[i][V_X];
  372.     np[i][V_Y] = dp[i][V_Y];
  373.     np[i][V_Z] = dp[i][V_Z];
  374.     }
  375.  
  376. poly(nv, np);
  377. }
  378.  
  379. /* ------------------------------------------------------------------------ */
  380.  
  381. /*
  382.  * polf2
  383.  *
  384.  *    construct a filled polygon from an (x, y) array of points provided
  385.  * by the user.
  386.  */
  387. void polf2(
  388.   long nv,
  389.   float dp[][2])
  390. {
  391. int    i;
  392. float    np[MAXVERTS][3];
  393.  
  394. if (!vdevice.initialised)
  395. verror("polf2: vogl not initialised");
  396.  
  397. vdevice.fill = polymodeflag;
  398.  
  399. for (i = 0; i < (int)nv; i++) {
  400.     np[i][V_X] = dp[i][V_X];
  401.     np[i][V_Y] = dp[i][V_Y];
  402.     np[i][V_Z] = 0.0;
  403.     }
  404.  
  405. poly(n